package main

import (
	"container/list"
	"fmt"
	"strconv"
)

type Date struct {
	year        int
	month       int
	day         int
	hour        int
	minute      int
	second      int
	millisecond int
}

type LogData struct {
	date       Date
	srcAddr    string
	dstAddr    string
	nextHop    string
	srcPort    int
	dstPort    int
	totalBytes float64
	packages   int
	srcAS      int
	dstAS      int
}

type Router struct {
	id         string
	mac        string
	ip         string
	sample     LogData
	neighbours *list.List
}

type Connection struct {
	routerA string
	routerB string
}

func getLog(router Router) LogData {
	return router.sample
}

func getRouterByIP(ip string, routers []Router) Router {
	var id, _ = strconv.Atoi(ip[11:13])
	return routers[id]
}

func traceAttack(log LogData) *list.List {
	//获取来源IP
	ipPointer := log.srcAddr
	//获取来源路由器
	routerPointer := getRouterByIP(ipPointer, routers)
	//获取来源日志
	logPointer := getLog(routerPointer)
	//初始化路径列表并将来源路由器编号放入
	path := list.New()
	path.PushBack(routerPointer.id)
	fmt.Println(routerPointer.id)
	//向通路上的路由器查询日志
	for logPointer.nextHop != "" {
		//获取下一跳IP
		ipPointer = logPointer.nextHop
		//获取下一跳路由器及其日志
		routerPointer = getRouterByIP(ipPointer, routers)
		logPointer = getLog(routerPointer)
		//将下一跳指向的路由器编号入列表
		path.PushBack(routerPointer.id)
		fmt.Println(routerPointer.id)
	}
	return path
}

var routers []Router

func main() {
	//初始化路由器群
	routers = make([]Router, 17)
	for i := 1; i < 17; i++ {
		routers[i] = Router{
			id:         strconv.Itoa(i),
			mac:        "",
			ip:         "",
			sample:     LogData{},
			neighbours: nil,
		}
		if i < 10 {
			routers[i].mac = "00-00-00-00-00-00-00-0" + strconv.Itoa(i)
			routers[i].ip = "192.168.1.10" + strconv.Itoa(i)
		} else {
			routers[i].mac = "00-00-00-00-00-00-00-" + strconv.Itoa(i)
			routers[i].ip = "192.168.1.1" + strconv.Itoa(i)
		}
		routers[i].neighbours = list.New()
	}
	//填充网络拓扑连接情况，并为路由器填充邻居
	var connections [14]Connection
	connections[0] = Connection{routerA: "1", routerB: "2"}
	connections[1] = Connection{routerA: "5", routerB: "6"}
	connections[2] = Connection{routerA: "9", routerB: "10"}
	connections[3] = Connection{routerA: "13", routerB: "14"}
	connections[4] = Connection{routerA: "6", routerB: "7"}
	connections[5] = Connection{routerA: "7", routerB: "12"}
	connections[6] = Connection{routerA: "11", routerB: "12"}
	connections[7] = Connection{routerA: "2", routerB: "6"}
	connections[8] = Connection{routerA: "3", routerB: "7"}
	connections[9] = Connection{routerA: "4", routerB: "8"}
	connections[10] = Connection{routerA: "6", routerB: "10"}
	connections[11] = Connection{routerA: "10", routerB: "14"}
	connections[12] = Connection{routerA: "11", routerB: "15"}
	connections[13] = Connection{routerA: "12", routerB: "16"}
	for i := 0; i < len(connections); i++ {
		var aString = connections[i].routerA
		var bString = connections[i].routerB
		var aInt, _ = strconv.Atoi(aString)
		var bInt, _ = strconv.Atoi(bString)
		routers[aInt].neighbours.PushBack(bString)
		routers[bInt].neighbours.PushBack(aString)
	}
	//分发样例报文
	routers[1].sample = LogData{
		date: Date{
			year:        2077,
			month:       11,
			day:         04,
			hour:        13,
			minute:      14,
			second:      15,
			millisecond: 596,
		},
		srcAddr:    "192.168.1.101",
		dstAddr:    "192.168.1.112",
		nextHop:    "192.168.1.102",
		srcPort:    80,
		dstPort:    1919,
		totalBytes: 1000,
		packages:   100,
		srcAS:      1919,
		dstAS:      810,
	}
	routers[2].sample = LogData{
		date: Date{
			year:        2077,
			month:       11,
			day:         04,
			hour:        13,
			minute:      14,
			second:      15,
			millisecond: 597,
		},
		srcAddr:    "192.168.1.101",
		dstAddr:    "192.168.1.112",
		nextHop:    "192.168.1.106",
		srcPort:    80,
		dstPort:    1919,
		totalBytes: 1000,
		packages:   100,
		srcAS:      1919,
		dstAS:      810,
	}
	routers[6].sample = LogData{
		date: Date{
			year:        2077,
			month:       11,
			day:         04,
			hour:        13,
			minute:      14,
			second:      15,
			millisecond: 598,
		},
		srcAddr:    "192.168.1.101",
		dstAddr:    "192.168.1.112",
		nextHop:    "192.168.1.107",
		srcPort:    80,
		dstPort:    1919,
		totalBytes: 1000,
		packages:   100,
		srcAS:      1919,
		dstAS:      810,
	}
	routers[7].sample = LogData{
		date: Date{
			year:        2077,
			month:       11,
			day:         04,
			hour:        13,
			minute:      14,
			second:      15,
			millisecond: 599,
		},
		srcAddr:    "192.168.1.101",
		dstAddr:    "192.168.1.112",
		nextHop:    "192.168.1.112",
		srcPort:    80,
		dstPort:    1919,
		totalBytes: 1000,
		packages:   100,
		srcAS:      1919,
		dstAS:      810,
	}
	routers[12].sample = LogData{
		date: Date{
			year:        2077,
			month:       11,
			day:         04,
			hour:        13,
			minute:      14,
			second:      15,
			millisecond: 600,
		},
		srcAddr:    "192.168.1.101",
		dstAddr:    "192.168.1.112",
		nextHop:    "",
		srcPort:    80,
		dstPort:    1919,
		totalBytes: 1000,
		packages:   100,
		srcAS:      1919,
		dstAS:      810,
	}
	//开始溯源
	//传入任一通路的NetFlow
	traceAttack(getLog(routers[7]))
}
